﻿/*********************************************************

    Copyright (c) Microsoft. All rights reserved.
    This code is licensed under the Microsoft Public License.
    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.

*********************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Xml.Linq;
using OData.Silverlight;

namespace SL_OData_Explorer.Utilities
{
    public interface IUserInfoWindow
    {
        string UserMessage { get; set; }
    }

    public static class IsolatedStorageUtility
    {

        public static void RemoveWorkspaceFromStorage(string workspaceName, string dataServiceUri)
        {
            string settingsFile = "ODataExplorerSettings.xml";
            string workspaceNodeName = "workSpace";
            //<workSpace name='{workspaceName}' Uri ='{dataServiceUri}' />
            try
            {
                using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    XElement xeWorkspaces = null;
                    string srContents = String.Empty;
                    #region Read workspaces from IsoStore
                    using (IsolatedStorageFileStream isfs = new IsolatedStorageFileStream(settingsFile, FileMode.OpenOrCreate, isf))
                    {

                        using (StreamReader sr = new StreamReader(isfs))
                        {
                            srContents = sr.ReadToEnd();
                            if (String.IsNullOrEmpty(srContents))
                            {
                                srContents = "<workSpaces></workSpaces>";

                            }

                        }
                        isfs.Close();
                    }
                    #endregion


                    xeWorkspaces = XElement.Parse(srContents, LoadOptions.PreserveWhitespace);

                    var deleteThisWorkspace = (from workspace in xeWorkspaces.Elements(workspaceNodeName)
                                               where workspace.Attribute("name").Value == workspaceName
                                               && workspace.Attribute("uri").Value.TrimEnd('/') == dataServiceUri.TrimEnd('/')
                                               select workspace).FirstOrDefault();

                    if (deleteThisWorkspace != null)
                    {
                        deleteThisWorkspace.RemoveNodes();
                        deleteThisWorkspace.Remove();
                    }
                    #region Write Values back to IsoStore
                    using (IsolatedStorageFileStream writeFileStream = new IsolatedStorageFileStream(settingsFile, FileMode.Truncate, isf))
                    {
                        using (StreamWriter streamWriter = new StreamWriter(writeFileStream))
                        {
                            xeWorkspaces.Save(streamWriter, SaveOptions.OmitDuplicateNamespaces);
                        }
                        writeFileStream.Close();
                    }
                    #endregion


                }
            }
            catch (IsolatedStorageException isoStoreException)
            {
                UIUtility.ShowMessageBox<UseInformation>(isoStoreException.Message);
            }
        }

        public static void AddWorkspaceToStorage(string workspaceName, string dataServiceUri)
        {
            string settingsFile = "ODataExplorerSettings.xml";
            string workspaceNodeName = "workSpace";
            //<workSpace name='{workspaceName}' Uri ='{dataServiceUri}' />
            try
            {
                using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    XElement xeWorkspaces = null;
                    #region Read workspaces from IsoStore
                    using (IsolatedStorageFileStream isfs = new IsolatedStorageFileStream(settingsFile, FileMode.OpenOrCreate, isf))
                    {

                        using (StreamReader sr = new StreamReader(isfs))
                        {
                            string srContents = sr.ReadToEnd();
                            if (String.IsNullOrEmpty(srContents))
                            {
                                srContents = "<workSpaces></workSpaces>";

                            }

                            xeWorkspaces = XElement.Parse(srContents, LoadOptions.PreserveWhitespace);

                            xeWorkspaces.Add(
                                    new XElement(workspaceNodeName,
                                            new XAttribute("name", workspaceName),
                                            new XAttribute("uri", dataServiceUri))
                                    );
                        }
                        isfs.Close();
                    }
                    #endregion

                    #region Write Values back to IsoStore
                    using (IsolatedStorageFileStream isfs = new IsolatedStorageFileStream(settingsFile, FileMode.OpenOrCreate, isf))
                    {
                        using (StreamWriter sr = new StreamWriter(isfs))
                        {
                            xeWorkspaces.Save(sr);
                        }
                        isfs.Close();
                    }
                    #endregion


                }
            }
            catch (IsolatedStorageException isoStoreException)
            {
                UIUtility.ShowMessageBox<UseInformation>(isoStoreException.Message);
            }
        }

        public static List<KeyValuePair<string, string>> GetWorkspacesFromStorage()
        {
            string settingsFile = "ODataExplorerSettings.xml";
            string workspaceNodeName = "workSpace";
            List<KeyValuePair<string, string>> workspacesInStorage = new List<KeyValuePair<string, string>>();
            if (IsolatedStorageFile.IsEnabled)
            {
                using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    using (IsolatedStorageFileStream isfs = new IsolatedStorageFileStream(settingsFile, FileMode.OpenOrCreate, isf))
                    {
                        using (StreamReader sr = new StreamReader(isfs))
                        {
                            string srContents = sr.ReadToEnd();
                            if (String.IsNullOrEmpty(srContents))
                            {
                                srContents = "<workSpaces></workSpaces>";
                            }
                            XElement xeWorkspaces = XElement.Parse(srContents, LoadOptions.PreserveWhitespace);
                            workspacesInStorage = (from workspaceNode in xeWorkspaces.Elements(workspaceNodeName)
                                                   select new KeyValuePair<string, string>(
                                                     workspaceNode.Attribute(XName.Get("name")).Value,
                                                     workspaceNode.Attribute(XName.Get("uri")).Value
                                                     )).ToList();
                        }
                    }
                }
            }
            return workspacesInStorage;
        }
    }
    public static class UIUtility
    {
        public static void ShowMessageBox<TWindowType>(string message) where TWindowType : ChildWindow, IUserInfoWindow, new()
        {
            TWindowType window = new TWindowType();
            window.UserMessage = message;
            window.Show();
        }

        public static void GenerateGridTemplate(DataGrid EntitySetGrid, ODataServiceContext serviceContext,
            EntityType entityType, IValueConverter dictionaryConverter,
            Action<ODataEntity, NavigationProperty> OnEntitySelected)
        {
            //Remove any existing columns on the DataGrid
            EntitySetGrid.Columns.Clear();
            if (entityType.FeedCustomizationMappings.Count == 0 && !entityType.HasComplexTypeProperties)
            {
                //Freeze the Edit Column
                EntitySetGrid.FrozenColumnCount = 1;
                //Add the EDIT button to show EDIT view
                EntitySetGrid.Columns.Add(
                    ControlBuilder.GetEditColumnTemplate(serviceContext)
                    );
            }
            else
            {
                EntitySetGrid.FrozenColumnCount = 0;
            }
            if (entityType.HasStream)
            {
                EntitySetGrid.Columns.Add(
                    ControlBuilder.GetMediaColumnTemplate(dictionaryConverter)
                    );
            }
            if (ApplicationSettings.Current.ShowNavigationProperties && OnEntitySelected != null)
            {
                foreach (NavigationProperty navigation in entityType.Navigations)
                {
                    EntitySetGrid.Columns.Add(
                        ControlBuilder.GetColumnTemplate(navigation, dictionaryConverter, OnEntitySelected)
                        );
                }
            }
            foreach (EntityProperty property in entityType.Properties.Where(prop => prop.PropertyType != typeof(byte[])))
            {
                EntitySetGrid.Columns.Add(
                    ControlBuilder.GetColumnTemplate(property, dictionaryConverter)
                    );
            }
        }

        public static void GenerateGridTemplate(DataGrid EntitySetGrid, EntitySet entitySet,
            ODataServiceContext serviceContext, IValueConverter dictionaryConverter
        , Action<ODataEntity, NavigationProperty> OnEntitySelected)
        {
            EntityType entityType = App.MDViewModel.CurrentModel.GetEntityType(entitySet);
            GenerateGridTemplate(EntitySetGrid, serviceContext, entityType, dictionaryConverter, OnEntitySelected);
        }
        public static void GenerateGridTemplate(DataGrid EntitySetGrid, string entitySetName, ODataServiceContext serviceContext,
            IValueConverter dictionaryConverter,
            Action<ODataEntity, NavigationProperty> OnEntitySelected)
        {
            EntitySet entitySet = App.MDViewModel.CurrentModel.GetEntitySet(entitySetName);
            GenerateGridTemplate(EntitySetGrid, entitySet, serviceContext, dictionaryConverter, OnEntitySelected);
        }
    }

    public class ScreenResolutionViewModel : INotifyPropertyChanged
    {
        private double _gridMaxHeight;
        public double GridMaxHeight
        {
            get
            {
                return _gridMaxHeight;
            }
            set
            {
                _gridMaxHeight = value;
                RaisePropertyChanged("GridMaxHeight");
            }
        }

        private double _gridMaxWidth;
        public double GridMaxWidth
        {
            get
            {
                return _gridMaxWidth;
            }
            set
            {
                _gridMaxWidth = value;
                RaisePropertyChanged("GridMaxWidth");
            }
        }

        private double _tabMaxHeight;
        public double TabMaxHeight
        {
            get
            {
                return _tabMaxHeight;
            }
            set
            {
                _tabMaxHeight = value;
                RaisePropertyChanged("TabMaxHeight");
            }
        }

        private double _tabMaxWidth;
        public double TabMaxWidth
        {
            get
            {
                return _tabMaxWidth;
            }
            set
            {
                _tabMaxWidth = value;
                RaisePropertyChanged("TabMaxWidth");
            }
        }



        private double _rawViewMaxHeight;
        public double RawViewMaxHeight
        {
            get
            {
                return _rawViewMaxHeight;
            }
            set
            {
                _rawViewMaxHeight = value;
                RaisePropertyChanged("RawViewMaxHeight");
            }
        }

        private void RaisePropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }
    public static class ValidationExtensions
    {
        public static void UpdateBindingSource(this FrameworkElement control, DependencyProperty propertyDependency)
        {
            BindingExpression bindingExpression = control.GetBindingExpression(propertyDependency);
            bindingExpression.UpdateSource();
        }
    }
}
